﻿using System;
using System.Diagnostics;
using System.Threading;
using log4net;
using Needle.Bus.Engine.Utils;

namespace Needle.Bus.Engine.Management
{
    public class PerfCounter : EngineComponent, IPerformanceCounter
    {

        ILog _log;

        public PerfCounter(string id)
            : this(new NamedMutex(id), id)
        { }

        public PerfCounter(object mutex, string id)
            : base(mutex, id)
        {
            _log = LogManager.GetLogger(id);
        }

        private int _isEnabled=1;
        public bool IsEnabled
        {
            get
            {
                return _isEnabled == 1;
            }
            set
            {
                int enable = value ? 1 : 0;
                Interlocked.CompareExchange(ref _isEnabled, enable, _isEnabled);
            }
        }

        public void Record(int sample)
        {
            Record(sample, Stopwatch.GetTimestamp(), 0);
        }

        public void Record(int sample, long timestamp)
        {
            Record(sample, timestamp, 0);
        }

        public void Record(double sample)
        {
            Record(sample, Stopwatch.GetTimestamp(), 0);
        }

        public void Record(double sample, long timestamp)
        {
            Record(sample, timestamp, 0);
        }

        public virtual void Record(int sample, long timestamp, long duration)
        {
            Record((double)sample, timestamp, duration);
        }

        public virtual void Record(double sample, long timestamp, long duration)
        {
            if (!IsEnabled)
                return;
            _log.DebugFormat(
                "{3,10} Stage {0} processed {1} messages in {2:N3} milliseconds", 
                Bus.Context.Stage.Id, 
                (int)sample, 
                TimeSpan.FromTicks(duration).TotalMilliseconds,
                timestamp
                );
        }

        protected override void OnOpen(TimeSpan timeout)
        {
            // TODO: implement
        }

        protected override void OnAbort()
        {
            // TODO: implement
        }

        protected override void OnClose(TimeSpan timeout)
        {
            // TODO: implement
        }
    }
}
